package com.tupu.util;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tupu.entity.admin.LabelInfo;
import com.tupu.entity.admin.LabelPropertyInfo;
import com.tupu.entity.admin.RelationInfo;
import com.tupu.entity.dispatch.WarningEventFailurePlan;
import com.tupu.entity.neo4j.*;
import com.tupu.mapper.admin.LabelMapper;
import com.tupu.mapper.admin.PropertyMapper;
import com.tupu.mapper.admin.RelationMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.neo4j.ogm.model.Property;
import org.neo4j.ogm.model.Result;
import org.neo4j.ogm.response.model.NodeModel;
import org.neo4j.ogm.response.model.RelationshipModel;
import org.neo4j.ogm.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@Component
public class Neo4jUtil {

    private static final ObjectMapper mapper = new ObjectMapper();

    static {
        mapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false);
    }

    @Resource
    private Session session;

    @Autowired(required = false)
    private LabelMapper labelMapper;

    @Autowired(required = false)
    private RelationMapper relationMapper;

    @Autowired(required = false)
    private PropertyMapper propertyMapper;

    /**
     * 根据图谱绑定node_id 查询实例的id及名称
     *
     * @param node_id
     * @return
     */
    public List<NodeSimple> findByNodeId(Long node_id, Long size) {
        List<NodeSimple> nodeList = new ArrayList<>();
        String cypherSql = String.format(" MATCH (n) where n.node_id='%s' RETURN n limit %s;", node_id, size);
        //System.out.println(cypherSql);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            NodeSimple nodeSimple = new NodeSimple();
            NodeModel queryNode = (NodeModel) map.get("n");
            //节点id
            nodeSimple.setId(queryNode.getId());
            //节点属性
            List<Property<String, Object>> propertyList = queryNode.getPropertyList();
            for (Property<String, Object> property : propertyList) {
                if (property.getKey().contains("name")) {
                    Object value = property.getValue();
                    nodeSimple.setName(value.toString());
                }
            }
            nodeList.add(nodeSimple);
        }
        session.clear();
        return nodeList;
    }

    /**
     * 新增实例节点
     *
     * @param node
     * @return
     */
    public void createNode(NodeSingle node) {
        //实体 标签名字
        String labelName = labelMapper.findlabelName(node.getLabelId());
        //处理属性
        Map<String, Object> properties = node.getAttrs();
        properties.put("node_id", "'" + node.getNodeId() + "'");
        //System.out.println("s:" + "'" + node.getNodeId() + "'");
        properties.put("name", node.getName());
        Set<String> keySet = properties.keySet();
        //Map转String
        //1、获取map的key的set集合 转换成String数组
        //2、循环String数组 拼接字符串 每个key value 一组间用 顿号隔开
        String[] array = keySet.toArray(new String[keySet.size()]);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < array.length; i++) {
            //参数值为空，则不参与签名 这个方法trim()是去空格
            if ((String.valueOf(properties.get(array[i]))).trim().length() > 0) {
                sb.append(array[i]).append(":").append(String.valueOf(properties.get(array[i])).trim());
            }
            if (i != array.length - 1) {
                sb.append(",");
            }
        }
        String cypherSql = String.format("create (n:`%s`{%s}) return n", labelName, sb);
        session.query(cypherSql, new HashMap<>());
        session.clear();
    }

    /**
     * 创建实例 节点 可视化
     *
     * @param node
     * @return
     */
    public Long createNodeVis(NodeSingle node) {
        //实体 标签名字
        String labelName = labelMapper.findlabelName(node.getLabelId());
        //处理属性
        Map<String, Object> properties = node.getAttrs();
        properties.put("node_id", "'" + node.getNodeId() + "'");
        properties.put("name", node.getName());
        Set<String> keySet = properties.keySet();
        //Map转String
        //1、获取map的key的set集合 转换成String数组
        //2、循环String数组 拼接字符串 每个key value 一组间用 顿号隔开
        String[] array = keySet.toArray(new String[keySet.size()]);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < array.length; i++) {
            //参数值为空，则不参与签名 这个方法trim()是去空格
            if ((String.valueOf(properties.get(array[i]))).trim().length() > 0) {
                sb.append(array[i]).append(":").append(String.valueOf(properties.get(array[i])).trim());
            }
            if (i != array.length - 1) {
                sb.append(",");
            }
        }
        String cypherSql = String.format("create (n:`%s`{%s}) return n", labelName, sb);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        Long id = null;
        for (Map<String, Object> map : maps) {
            NodeModel queryNode = (NodeModel) map.get("n");
            id = queryNode.getId();
        }
        session.clear();
        return id;
    }

    /**
     * 根据实例id删除节点
     *
     * @param id
     * @return
     */
    public void delNode(Long id) {
        String cypherSql = String.format("match(n) where ID(n)=%s detach delete n", id);
        session.query(cypherSql, new HashMap<>());
        session.clear();
    }

    /**
     * 修改 更新节点信息
     *
     * @param node
     * @return
     */
    public void updateNode(NodeSingle node) {
        //通过id查找更新属性
        Long id = node.getId();
        //获取名称
        String name = "";
        String cypherSqlFindName = String.format("match (n) where id(n) = %s return n", id);
        Result query = session.query(cypherSqlFindName, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            NodeModel queryNode = (NodeModel) map.get("n");
            List<Property<String, Object>> propertyList = queryNode.getPropertyList();
            for (Property<String, Object> stringObjectProperty : propertyList) {
                if (stringObjectProperty.getKey().equals("name")) {
                    Object value = stringObjectProperty.getValue();
                    name = value.toString();
                }
            }
        }
        //获取属性
        Map<String, Object> attrs = node.getAttrs();
        Set<String> set = attrs.keySet();
        //Map转为String 拼接
        String[] strings = set.toArray(new String[set.size()]);
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < strings.length; i++) {
            if ((String.valueOf(attrs.get(strings[i]))).trim().length() > 0) {
                builder.append("r.").append(strings[i]).append("=").append(String.valueOf(attrs.get(strings[i])).trim());
            }
            if (i != strings.length - 1) {
                builder.append(",");
            }
        }
        if (StringUtils.isNotEmpty(node.getName())) {
            builder.append(",").append("r.").append("name").append("=").append(node.getName());
        } else {
            builder.append(",").append("r.").append("name").append("=").append("'").append(name).append("'");
        }
        String cypherSql = String.format("match (r) where id(r)= %s set %s", id, builder);
        session.query(cypherSql, new HashMap<>());
        session.clear();
    }

    /**
     * 创建节点间关系
     *
     * @param
     * @return
     */
    public void CreateRelation(Long startId, Long endId, Long typeId) {
        String type = relationMapper.findRelationName(typeId);
        RelationInfo relationList = relationMapper.selectById(typeId);
        Long nodeId = relationList.getNodeId();
        String cypherSql = String.format
                ("match (a),(b) where id(a)=%s and id(b)=%s create (a) - [r:`%s`{node_id:'%s'}] -> (b) return r", startId, endId, type, nodeId);
        session.query(cypherSql, new HashMap<>());
        session.clear();
    }

    /**
     * 通过节点id查询所有属性
     *
     * @param id
     * @return
     */
    public List<Map<String, Object>> findById(Long id) {
        List<Map<String, Object>> list = new ArrayList<>();
        String cypherSql = String.format("match (n) where id(n) = %s return n", id);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            //获取属性
            NodeModel queryNode = (NodeModel) map.get("n");
            List<Property<String, Object>> propertyList = queryNode.getPropertyList();
            Map<String, Object> proMap = new HashMap<>();
            for (Property<String, Object> stringObjectProperty : propertyList) {
                if (proMap.containsKey(stringObjectProperty.getKey())) {
                    throw new RuntimeException("数据重复");
                }
                proMap.put("id", id);
                proMap.put(stringObjectProperty.getKey(), stringObjectProperty.getValue());
            }
            String[] label = queryNode.getLabels();
            for (String l : label) {
                proMap.put("label", l);
            }
            list.add(proMap);
        }
        session.clear();
        return list;
    }

    /**
     * 通过节点id查询标签名称
     *
     * @param case_id
     * @return
     */
    public String findByCaseId(Long case_id) {
        String cypherSql = String.format("match (n) where id(n) = %s return n", case_id);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        String label = "";
        for (Map<String, Object> map : maps) {
            //获取标签
            NodeModel queryNode = (NodeModel) map.get("n");
            String[] labels = queryNode.getLabels();
            for (String l : labels) {
                label = l;
            }
        }
        session.clear();
        return label;
    }

    /**
     * 根据独立node_id和标签区分多图谱
     *
     * @param label
     * @param node_id
     * @return
     */
    public List<NodeSingle> findByLabelAndNodeId(String label, Long node_id, String case_name) {
        List<NodeSingle> arrayList = new ArrayList<>();
        String cypherSql = "";
        if (null == case_name) {
            cypherSql = String.format("match (n:`%s`) where n.node_id = '%s' return n", label, node_id);
        } else {
            cypherSql = String.format("match (n:`%s`) where n.node_id = '%s' and n.name=~'.*%s.*' return n", label, node_id, case_name);
        }
        //System.out.println(cypherSql);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            NodeSingle node = new NodeSingle();
            NodeModel queryNode = (NodeModel) map.get("n");
            //节点id
            node.setId(queryNode.getId());
            node.setName(label);
            //节点属性
            List<Property<String, Object>> propertyList = queryNode.getPropertyList();
            Map<String, Object> proMap = new HashMap<>();
            for (Property<String, Object> property : propertyList) {
                if (proMap.containsKey(property.getKey())) {
                    throw new RuntimeException("数据重复");
                }
                proMap.put(property.getKey(), property.getValue());
                node.setAttrs(proMap);
            }
            arrayList.add(node);
        }
        session.clear();
        return arrayList;
    }

    /**
     * 根据独立node_id 区分多图谱
     *
     * @param node_id
     * @return
     */
    public List<NodeSingle> findByNid(Long node_id) {
        List<NodeSingle> arrayList = new ArrayList<>();
        String cypherSql = String.format("match (n) where n.node_id = '%s' return n limit 100", node_id);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            NodeSingle node = new NodeSingle();
            NodeModel queryNode = (NodeModel) map.get("n");
            //节点id
            node.setId(queryNode.getId());
            node.setName(queryNode.getLabels().toString());
            //节点属性
            List<Property<String, Object>> propertyList = queryNode.getPropertyList();
            Map<String, Object> proMap = new HashMap<>();
            for (Property<String, Object> property : propertyList) {
                if (proMap.containsKey(property.getKey())) {
                    throw new RuntimeException("数据重复");
                }
                proMap.put(property.getKey(), property.getValue());
                node.setAttrs(proMap);
            }
            arrayList.add(node);
        }
        session.clear();
        return arrayList;
    }

    /**
     * 查询一个关系id 查找实例数据
     *
     * @return
     */
    public RelationListAll findOneRelation(Long relation_id) {
        String cypherSql = String.format("MATCH (a)-[r]-(b) where id(r) = %s return r;", relation_id);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        RelationListAll relation = new RelationListAll();
        for (Map<String, Object> map : maps) {
            RelationshipModel relationshipModel = (RelationshipModel) map.get("r");
            relation.setRelation_id(relation_id);
            Long startId = relationshipModel.getStartNode();
            relation.setStartId(startId);
            //查询开始节点
            String cypherSql1 = String.format("MATCH (n) where id(n) = %s return n;", startId);
            Result query1 = session.query(cypherSql1, new HashMap<>());
            Iterable<Map<String, Object>> maps1 = query1.queryResults();
            for (Map<String, Object> map1 : maps1) {
                NodeModel queryNode = (NodeModel) map1.get("n");
                List<Property<String, Object>> propertyList = queryNode.getPropertyList();
                for (Property<String, Object> pro : propertyList) {
                    if (pro.getKey().equals("name")) {
                        relation.setStartName(pro.getValue().toString());
                    }
                }
            }
            //查询终点节点
            Long endId = relationshipModel.getEndNode();
            relation.setEndId(endId);
            String cypherSql2 = String.format("MATCH (n) where id(n) = %s return n;", endId);
            Result query2 = session.query(cypherSql2, new HashMap<>());
            Iterable<Map<String, Object>> maps2 = query2.queryResults();
            for (Map<String, Object> map2 : maps2) {
                NodeModel queryNode = (NodeModel) map2.get("n");
                List<Property<String, Object>> propertyList = queryNode.getPropertyList();
                for (Property<String, Object> pro : propertyList) {
                    if (pro.getKey().equals("name")) {
                        relation.setEndName(pro.getValue().toString());
                    }
                }
            }
            relation.setType(relationshipModel.getType());
            session.clear();
        }
        return relation;
    }

    /**
     * 查询关系名称 查找实例数据
     *
     * @return
     */
    public List<RelationListAll> findRelationByName(String relation_name, Long node_id) {
        List<RelationListAll> relaList = new ArrayList<>();
        String cypherSql = String.format("MATCH ()-[r]-() where type(r) = '%s' and r.node_id = '%s' return r;", relation_name, node_id);
        System.out.println(cypherSql);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            RelationListAll relation = new RelationListAll();
            RelationshipModel relationshipModel = (RelationshipModel) map.get("r");
            Long id = relationshipModel.getId();
            relation.setRelation_id(id);
            Long startId = relationshipModel.getStartNode();
            relation.setStartId(startId);
            //查询开始节点
            String cypherSql1 = String.format("MATCH (n) where id(n) = %s return n;", startId);
            Result query1 = session.query(cypherSql1, new HashMap<>());
            Iterable<Map<String, Object>> maps1 = query1.queryResults();
            for (Map<String, Object> map1 : maps1) {
                NodeModel queryNode = (NodeModel) map1.get("n");
                List<Property<String, Object>> propertyList = queryNode.getPropertyList();
                for (Property<String, Object> pro : propertyList) {
                    if (pro.getKey().equals("name")) {
                        relation.setStartName(pro.getValue().toString());
                    }
                }
            }
            //查询终点节点
            Long endId = relationshipModel.getEndNode();
            relation.setEndId(endId);
            String cypherSql2 = String.format("MATCH (n) where id(n) = %s return n;", endId);
            Result query2 = session.query(cypherSql2, new HashMap<>());
            Iterable<Map<String, Object>> maps2 = query2.queryResults();
            for (Map<String, Object> map2 : maps2) {
                NodeModel queryNode = (NodeModel) map2.get("n");
                List<Property<String, Object>> propertyList = queryNode.getPropertyList();
                for (Property<String, Object> pro : propertyList) {
                    if (pro.getKey().equals("name")) {
                        relation.setEndName(pro.getValue().toString());
                    }
                }
            }
            relation.setType(relationshipModel.getType());

            relaList.add(relation);
            session.clear();
        }
        return relaList;
    }

    /**
     * 根据关系id删除节点间关系
     *
     * @param relation_id
     * @return
     */
    public void delRelationById(Long relation_id) {
        String cypherSql = String.format("match (p1)-[r]-(p2) where id(r)=%s delete r", relation_id);
        session.query(cypherSql, new HashMap<>());
        session.clear();
    }

    /**
     * 根据node_id查询关系列表
     *
     * @param node_id
     */
    public List<RelationListAll> findRelationByNodeId(Long node_id) {
        List<RelationListAll> relaList = new ArrayList<>();
        String cypherSql = String.format("MATCH ()-[r]-() where r.node_id = '%s' return distinct r;", node_id);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            RelationListAll relation = new RelationListAll();
            RelationshipModel relationshipModel = (RelationshipModel) map.get("r");
            Long startId = relationshipModel.getStartNode();
            relation.setStartId(startId);
            Long endId = relationshipModel.getEndNode();
            relation.setEndId(endId);
            relation.setType(relationshipModel.getType());
            relaList.add(relation);
            session.clear();
        }
        return relaList;
    }

    /**
     * 模糊查询实例节点 分页
     *
     * @param name
     * @param node_id
     * @return
     */
    public List<NodeSingle> findNodeByName(String name,
                                           Long node_id,
                                           Long page,
                                           Long size) {
        List<NodeSingle> arrayList = new ArrayList<>();
        String cypherSql = "";
        if (StringUtils.isNotEmpty(name)) {
            cypherSql = String.format("match (n) where n.name =~'.*%s.*' and n.node_id='%s' return n order by id(n) asc", name, node_id);
        } else {
            cypherSql = String.format("match (n) where n.node_id='%s' return n order by id(n) asc", node_id);
        }
        cypherSql = cypherSql + String.format(" skip %s limit %s;", (page - 1) * size, size);
        //System.out.println(cypherSql);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            NodeSingle node = new NodeSingle();
            List<String> keys = new ArrayList<>();
            List<String> values = new ArrayList<>();
            NodeModel queryNode = (NodeModel) map.get("n");
            //节点id
            node.setId(queryNode.getId());
            String[] labels = queryNode.getLabels();
            for (String s : labels) {
                node.setName(s);
            }
            //节点属性
            List<Property<String, Object>> propertyList = queryNode.getPropertyList();
            Map<String, Object> proMap = new HashMap<>();
            for (Property<String, Object> property : propertyList) {
                keys.add(property.getKey());
                if (!property.getKey().equals("name") && !property.getKey().equals("node_id") && !property.getKey().equals("uid"))
                    values.add(String.valueOf(property.getValue()));
                proMap.put(property.getKey(), property.getValue());
                node.setAttrs(proMap);
            }
            keys.remove("name");
            keys.remove("node_id");
            keys.remove("uid");
            node.setKey(keys);
            node.setValue(values);
            arrayList.add(node);
        }
        session.clear();
        return arrayList;
    }

    /**
     * 查询满足条件的实例总条数
     *
     * @return
     */
    public Long findAllNodeCount(String name, Long node_id) {
        String cypherSql = "";
        if (StringUtils.isNotEmpty(name)) {
            cypherSql = String.format("match (n) where n.name =~'.*%s.*' and n.node_id='%s' return count(n)", name, node_id);
        } else {
            cypherSql = String.format("match (n) where n.node_id='%s' return count(n)", node_id);
        }
        Result result = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = result.queryResults();
        Long total = null;
        for (Map<String, Object> map : maps) {
            total = (Long) map.get("count(n)");
        }
        session.clear();
        return total;
    }

    /**
     * 根据实例id 查询名称
     *
     * @param id
     * @return
     */
    public String findNameById(Long id) {
        String cypherSql = String.format("match (n) where id(n)= %s return n.name", id);
        Result result = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = result.queryResults();
        String name = "";
        for (Map<String, Object> map : maps) {
            name = (String) map.get("n.name");
        }
        session.clear();
        return name;
    }

    /**
     * 模糊查询关系 分页
     *
     * @param name
     * @param node_id
     * @param page
     * @param size
     * @return
     */
    public List<RelationListAll> findRelationByName(String name,
                                                    Long node_id,
                                                    Long page,
                                                    Long size) {
        List<RelationListAll> arrayList = new ArrayList<>();
        String cypherSql = "";
        if (StringUtils.isNotEmpty(name)) {
            cypherSql = String.format("match ()-[r]-() where type(r) =~'.*%s.*' and r.node_id='%s' return distinct r order by id(r) asc", name, node_id);
        } else {
            cypherSql = String.format("match ()-[r]-() where r.node_id='%s' return distinct r order by id(r) asc", node_id);
        }
        cypherSql = cypherSql + String.format(" skip %s limit %s;", (page - 1) * size, size);
        log.info(cypherSql);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            RelationListAll relation = new RelationListAll();
            RelationshipModel relationshipModel = (RelationshipModel) map.get("r");
            Long startNode = relationshipModel.getStartNode();
            Long endNode = relationshipModel.getEndNode();
            relation.setRelation_id(relationshipModel.getId());
            relation.setStartId(startNode);
            relation.setEndId(endNode);
            relation.setType(relationshipModel.getType());
            arrayList.add(relation);
        }
        session.clear();
        return arrayList;
    }

    /**
     * 查询满足条件的关系总条数
     *
     * @param name
     * @param node_id
     * @return
     */
    public Long findAllRelationCount(String name, Long node_id) {
        String cypherSql = "";
        if (StringUtils.isNotEmpty(name)) {
            cypherSql = String.format("match ()-[r]-() where type(r) =~'.*%s.*' and r.node_id ='%s' return count(r)", name, node_id);
        } else {
            cypherSql = String.format("match ()-[r]-() where r.node_id ='%s' return count(r)", node_id);
        }
        Result result = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = result.queryResults();
        Long total = null;
        for (Map<String, Object> map : maps) {
            total = (Long) map.get("count(r)");
        }
        session.clear();
        return total / 2;
    }

    /**
     * 查询node_id 查询详细实例信息
     *
     * @param node_id
     * @return
     */
    public List<NodeSingle> findNodeByNodeId(Long node_id) {
        List<NodeSingle> arrayList = new ArrayList<>();
        String cypherSql = String.format("match (n) where n.node_id='%s' return n order by id(n) asc", node_id);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            NodeSingle node = new NodeSingle();
            List<String> keys = new ArrayList<>();
            List<String> values = new ArrayList<>();
            NodeModel queryNode = (NodeModel) map.get("n");
            //节点id
            node.setId(queryNode.getId());
            String[] labels = queryNode.getLabels();
            for (String s : labels) {
                node.setName(s);
            }
            //节点属性
            List<Property<String, Object>> propertyList = queryNode.getPropertyList();
            Map<String, Object> proMap = new HashMap<>();
            for (Property<String, Object> property : propertyList) {
                keys.add(property.getKey());
                if (!property.getKey().equals("name") && !property.getKey().equals("node_id") && !property.getKey().equals("uid"))
                    values.add(String.valueOf(property.getValue()));
                proMap.put(property.getKey(), property.getValue());
                node.setAttrs(proMap);
            }
            keys.remove("name");
            keys.remove("node_id");
            keys.remove("uid");
            node.setKey(keys);
            node.setValue(values);
            arrayList.add(node);
        }
        session.clear();
        return arrayList;
    }

    /**
     * 根据node_id查询关系
     *
     * @param node_id
     * @return
     */
    public List<RelationListAll> findAllRelationByNodeId(Long node_id) {
        List<RelationListAll> arrayList = new ArrayList<>();
        String cypherSql = String.format("match ()-[r]-() where r.node_id='%s' return distinct r order by id(r) asc", node_id);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            RelationListAll relation = new RelationListAll();
            RelationshipModel relationshipModel = (RelationshipModel) map.get("r");
            Long startNode = relationshipModel.getStartNode();
            Long endNode = relationshipModel.getEndNode();
            relation.setRelation_id(relationshipModel.getId());
            relation.setStartId(startNode);
            relation.setEndId(endNode);
            relation.setType(relationshipModel.getType());
            arrayList.add(relation);
        }
        session.clear();
        return arrayList;
    }

    /**
     * 根据图谱id，node_id删除所有
     *
     * @param node_id
     * @return
     */
    public void delAllByNodeId(Long node_id) {
        String cypherSql = String.format("match (n) where n.node_id = '%s' detach delete n", node_id);
        session.query(cypherSql, new HashMap<>());
        session.clear();
    }

    /**
     * 导入实例csv文件
     *
     * @param file_path
     * @param label
     * @param propertyList
     */
    public void importCsvNode(String file_path, String label, List<String> propertyList, Long node_id) {
        //String cypherSql1 = "load csv with headers from 'file://";
        String cypherSql1 = "load csv with headers from '";
        String cypherSql2 = String.format("%s' as line create (:`%s`{uid:line['uid'],name:line['name']", file_path, label);
        StringBuilder cypherSql3 = new StringBuilder();
        if (!propertyList.isEmpty() && propertyList.size() > 0) {
            for (String property : propertyList) {
                cypherSql3.append(",").append("`").append(property).append("`").append(":line['").append(property).append("']");
            }
        }
        String cypherSql4 = String.format(",node_id:'%s'});", node_id);
        String cypherSql = cypherSql1 + cypherSql2 + cypherSql3 + cypherSql4;
        System.out.println(cypherSql);
        session.query(cypherSql, new HashMap<>());
        session.clear();
    }

    /**
     * 导入实例关系csv文件
     *
     * @param file_path
     * @param type
     * @param node_id
     */
    public void importCsvRelation(String file_path, String type, Long node_id) {
        String cypherSql1 = "load csv with headers from '";
        //String cypherSql1 = "load csv with headers from 'file://";
        String cypherSql2 = String.format("%s' as line match (from{uid:line['START_ID']}),(to{uid:line['END_ID']})", file_path);
        String cypherSql3 = String.format(" merge (from)-[r:`%s`{node_id:'%s'}]->(to)", type, node_id);
        String cypherSql = cypherSql1 + cypherSql2 + cypherSql3;
        System.out.println(cypherSql);
        session.query(cypherSql, new HashMap<>());
        session.clear();
    }

    /**
     * 高级搜索 实例节点
     *
     * @param node_id
     * @param label_id
     * @param property_id
     * @param property
     * @return
     */
    public List<NodeSimple> nodeAdvancedSearch(Long node_id, Long label_id, Long property_id, String property) {
        List<NodeSimple> nodeList = new ArrayList<>();
        LabelInfo label = labelMapper.selectById(label_id);
        LabelPropertyInfo propertyInfo = propertyMapper.selectById(property_id);
        String cypherSql = String.format("match (n:%s{%s:'%s',node_id:'%s'}) return n", label.getLabel(), propertyInfo.getName(), property, node_id);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            NodeSimple nodeSimple = new NodeSimple();
            NodeModel queryNode = (NodeModel) map.get("n");
            //节点id
            nodeSimple.setId(queryNode.getId());
            //节点属性
            List<Property<String, Object>> propertyList = queryNode.getPropertyList();
            for (Property<String, Object> pro : propertyList) {
                if (pro.getKey().contains("name")) {
                    Object value = pro.getValue();
                    nodeSimple.setName(value.toString());
                }
            }
            nodeList.add(nodeSimple);
        }
        session.clear();
        return nodeList;
    }

    /**
     * 节点关系搜索
     *
     * @param node_id
     * @param relation
     * @return
     */
    public List<RelationListAll> relationSearch(Long node_id, String relation) {
        List<RelationListAll> list = new ArrayList<>();
        String cypherSql = String.format("match (x{node_id:'%s'})-[r:`%s`{node_id:'%s'}]-(y{node_id:'%s'}) return x,r,y", node_id, relation, node_id, node_id);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            RelationListAll node = new RelationListAll();
            RelationshipModel relationshipModel = (RelationshipModel) map.get("r");
            Long startNode = relationshipModel.getStartNode();
            Long endNode = relationshipModel.getEndNode();
            String type = relationshipModel.getType();
            node.setStartId(startNode);
            node.setEndId(endNode);
            node.setType(type);
            list.add(node);
        }
        session.clear();
        return list;
    }

    /**
     * 节点关系高级搜索
     *
     * @param cypherSql
     * @return
     */
    public List<RelationListAll> relationAdvancedSearch(String cypherSql) {
        List<RelationListAll> list = new ArrayList<>();
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            RelationListAll node = new RelationListAll();
            RelationshipModel relationshipModel = (RelationshipModel) map.get("r");
            Long startNode = relationshipModel.getStartNode();
            Long endNode = relationshipModel.getEndNode();
            String type = relationshipModel.getType();
            node.setStartId(startNode);
            node.setEndId(endNode);
            node.setType(type);
            list.add(node);
        }
        session.clear();
        return list;
    }

    /**
     * 根据标签和属性查询所有属性值
     *
     * @param label
     * @param node_id
     * @param property
     * @return
     */
    public List<String> findAllProperty(String label, Long node_id, String property) {
        String cypherSql = String.format("match (n:%s{node_id:'%s'}) return n.%s", label, node_id, property);
        Result result = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = result.queryResults();
        List<String> list = new ArrayList<>();
        for (Map<String, Object> map : maps) {
            String s = String.format("n.%s", property);
            String pro = (String) map.get(s);
            list.add(pro);
        }
        session.clear();
        return list;
    }

    /**
     * 最短路径
     *
     * @param node_id
     * @param start_label
     * @param start_pro
     * @param start_property
     * @param end_label
     * @param end_pro
     * @param end_property
     * @return
     */
    public List<RelationListAll> shortestPath(Long node_id, String start_label, String start_pro, String start_property, String end_label, String end_pro, String end_property) {
        List<RelationListAll> relationList = new ArrayList<>();
        String cypherSql = String.format("MATCH (x:`%s`{`%s`:'%s',node_id:'%s'}),(y:`%s`{`%s`:'%s',node_id:'%s'}),p=shortestpath((x)-[r*..10]-(y)) RETURN r", start_label, start_pro, start_property, node_id, end_label, end_pro, end_property, node_id);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            List<RelationshipModel> relationshipModels = (List<RelationshipModel>) map.get("r");
            for (RelationshipModel r : relationshipModels) {
                RelationListAll rela = new RelationListAll();
                rela.setStartId(r.getStartNode());
                rela.setEndId(r.getEndNode());
                rela.setType(r.getType());
                relationList.add(rela);
            }
        }
        session.clear();
        return relationList;
    }

    /**
     * 查找所有节点名称
     *
     * @param node_id
     * @return
     */
    public List<NodeSimple> findAllNodeByNodeId(Long node_id) {
        List<NodeSimple> arrayList = new ArrayList<>();
        String cypherSql = String.format("match (n) where n.node_id='%s' return n order by id(n) asc", node_id);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            NodeSimple node = new NodeSimple();
            NodeModel queryNode = (NodeModel) map.get("n");
            //节点id
            node.setId(queryNode.getId());
            //节点属性
            List<Property<String, Object>> propertyList = queryNode.getPropertyList();
            for (Property<String, Object> property : propertyList) {
                if (property.getKey().equals("name")) {
                    node.setName(String.valueOf(property.getValue()));
                }
            }
            arrayList.add(node);
        }
        session.clear();
        return arrayList;
    }

    /**
     * 节点层级显示
     *
     * @param node_id
     * @param type
     * @param case_id
     * @return
     */
    public List<RelationListAll> levelVis(Long node_id, Long type, String case_id) {
        List<RelationListAll> relationList = new ArrayList<>();
        String cypherSql = String.format("match p=(x)-[r*1..%s]-(y{node_id:'%s'}) where id(x)= %s return r", type, node_id, case_id);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            List<RelationshipModel> relationshipModels = (List<RelationshipModel>) map.get("r");
            for (RelationshipModel r : relationshipModels) {
                RelationListAll rela = new RelationListAll();
                rela.setStartId(r.getStartNode());
                rela.setEndId(r.getEndNode());
                rela.setType(r.getType());
                relationList.add(rela);
            }
        }
        session.clear();
        return relationList;
    }

    /**
     * 根据图谱id，关系名称，删除节点间关系
     *
     * @param node_id
     * @param relation
     */
    public void delRelationByNodeIdAndName(Long node_id, String relation) {
        String cypherSql = String.format("match (a)-[r:`%s`{node_id:'%s'}]-(b) delete r;", relation, node_id);
        session.query(cypherSql, new HashMap<>());
        session.clear();
    }

    /**
     * 通过图谱id和标签名 查询实例id
     *
     * @param node_id
     * @param label
     * @return
     */
    public List<Long> findAllByNodeIdAndLabel(Long node_id, String label) {
        List<Long> list = new ArrayList<>();
        String cypherSql = String.format("match (n:`%s`{node_id:'%s'}) return n;", label, node_id);
        session.query(cypherSql, new HashMap<>());
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            NodeModel queryNode = (NodeModel) map.get("n");
            Long id = queryNode.getId();
            list.add(id);
        }
        session.clear();
        return list;
    }

    /**
     * 修改标签名
     *
     * @param old_label
     * @param new_label
     * @param node_id
     */
    public void updateLabel(String old_label, String new_label, Long node_id) {
        String cypherSql = String.format("match (n:`%s`{node_id:'%s'}) remove n:`%s` set n:`%s`;", old_label, node_id, old_label, new_label);
        session.query(cypherSql, new HashMap<>());
        session.clear();
    }

    /**
     * 修改实例关系名
     *
     * @param old_name
     * @param new_name
     * @param node_id
     */
    public void updateRelation(String old_name, String new_name, Long node_id) {
        String cypherSql = String.format("match (n)-[r:`%s`{node_id:'%s'}]->(m) create(n)-[r2:`%s`{node_id:'%s'}]->(m) set r2=r with r delete r;", old_name, node_id, new_name, node_id);
        //System.out.println(cypherSql);
        session.query(cypherSql, new HashMap<>());
        session.clear();
    }

    /**
     * 删除实例属性
     *
     * @param node_id
     * @param label
     * @param property
     */
    public void delProperty(Long node_id, String label, String property) {
        String cypherSql = String.format("match (n:`%s`) where n.node_id='%s' remove n.`%s`", label, node_id, property);
        System.out.println(cypherSql);
        session.query(cypherSql, new HashMap<>());
        session.clear();
    }

    /**
     * 根据实例id，编辑实例属性名
     *
     * @param id
     * @param new_pro
     * @param old_pro
     */
    public void updateProperty(Long id, String new_pro, String old_pro) {
        String cypherSql = String.format("match (n) where id(n)=%s set n.`%s` = n.`%s` remove n.`%s`", id, new_pro, old_pro, old_pro);
        session.query(cypherSql, new HashMap<>());
        session.clear();
    }

    /**
     * 根据图谱id和标签名称，查询所有节点id
     *
     * @param label
     * @param node_id
     * @return
     */
    public List<Long> allIds(String label, Long node_id) {
        List<Long> list = new ArrayList<>();
        String cypherSql = String.format("match (n:`%s`{node_id:'%s'}) return id(n) as a", label, node_id);
        //System.out.println(cypherSql);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> results = query.queryResults();
        for (Map<String, Object> map : results) {
            Long id = (Long) map.get("a");
            list.add(id);
        }
        session.clear();
        return list;
    }

    /**
     * 模糊查询名称
     *
     * @param name
     * @return
     */
    public List<NodeSingle> vagueSearchNodeByName(String name, Long node_id) {
        List<NodeSingle> arrayList = new ArrayList<>();

        String cypherSql = String.format("match (n) where n.name =~'.*%s.*' and n.node_id='%s' return n order by id(n) asc", name, node_id);

        System.out.println(cypherSql);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            NodeSingle node = new NodeSingle();
            List<String> keys = new ArrayList<>();
            List<String> values = new ArrayList<>();
            NodeModel queryNode = (NodeModel) map.get("n");
            //节点id
            node.setId(queryNode.getId());
            String[] labels = queryNode.getLabels();
            for (String s : labels) {
                node.setName(s);
            }
            //节点属性
            List<Property<String, Object>> propertyList = queryNode.getPropertyList();
            Map<String, Object> proMap = new HashMap<>();
            for (Property<String, Object> property : propertyList) {
                keys.add(property.getKey());
                if (!property.getKey().equals("name") && !property.getKey().equals("node_id") && !property.getKey().equals("uid"))
                    values.add(String.valueOf(property.getValue()));
                proMap.put(property.getKey(), property.getValue());
                node.setAttrs(proMap);
            }
            keys.remove("name");
            keys.remove("node_id");
            keys.remove("uid");
            node.setKey(keys);
            node.setValue(values);
            arrayList.add(node);
        }
        session.clear();
        return arrayList;
    }

    /**
     * 根据厂站 故障设置查询节点信息
     *
     * @param stationName
     * @param faultSetting
     * @param node_id
     * @return
     */
    public List<NodeSingle> vagueSearchNodeByAttrs(String stationName, String faultSetting, Long node_id) {

        List<NodeSingle> arrayList = new ArrayList<>();

        String cypherSql = String.format("match (n) where n.name =~'.*%s.*' and n.`故障设置`=~'.*%s.*'and n.node_id='%s' return n order by id(n) asc", stationName, faultSetting, node_id);

        System.out.println(cypherSql);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            NodeSingle node = new NodeSingle();
            List<String> keys = new ArrayList<>();
            List<String> values = new ArrayList<>();
            NodeModel queryNode = (NodeModel) map.get("n");
            //节点id
            node.setId(queryNode.getId());
            String[] labels = queryNode.getLabels();
            for (String s : labels) {
                node.setName(s);
            }
            //节点属性
            List<Property<String, Object>> propertyList = queryNode.getPropertyList();
            Map<String, Object> proMap = new HashMap<>();
            for (Property<String, Object> property : propertyList) {
                keys.add(property.getKey());
                if (!property.getKey().equals("name") && !property.getKey().equals("node_id") && !property.getKey().equals("uid"))
                    values.add(String.valueOf(property.getValue()));
                proMap.put(property.getKey(), property.getValue());
                node.setAttrs(proMap);
            }
            keys.remove("name");
            keys.remove("node_id");
            keys.remove("uid");
            node.setKey(keys);
            node.setValue(values);
            arrayList.add(node);
        }
        session.clear();
        return arrayList;
    }


/*    public void test() {
        //实体 标签名字
        String labelName = labelMapper.findlabelName(node.getLabelId());
        //处理属性
        Map<String, Object> properties = node.getAttrs();
        properties.put("node_id", "'" + node.getNodeId() + "'");
        //System.out.println("s:" + "'" + node.getNodeId() + "'");
        properties.put("name", node.getName());
        Set<String> keySet = properties.keySet();
        //Map转String
        //1、获取map的key的set集合 转换成String数组
        //2、循环String数组 拼接字符串 每个key value 一组间用 顿号隔开
        String[] array = keySet.toArray(new String[keySet.size()]);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < array.length; i++) {
            //参数值为空，则不参与签名 这个方法trim()是去空格
            if ((String.valueOf(properties.get(array[i]))).trim().length() > 0) {
                sb.append(array[i]).append(":").append(String.valueOf(properties.get(array[i])).trim());
            }
            if (i != array.length - 1) {
                sb.append(",");
            }
        }
        String cypherSql = String.format("create (n:`%s`{%s}) return n", labelName, sb);
        System.out.println();
        session.query(cypherSql, new HashMap<>());
        session.clear();
    }


    //处理属性
    Map<String, Object> properties = node.getAttrs();
                properties.put("node_id", "'" + node.getNodeId() + "'");
    //System.out.println("s:" + "'" + node.getNodeId() + "'");
                properties.put("name", node.getName());
    Set<String> keySet = properties.keySet();
    //Map转String
    //1、获取map的key的set集合 转换成String数组
    //2、循环String数组 拼接字符串 每个key value 一组间用 顿号隔开
    String[] array = keySet.toArray(new String[keySet.size()]);
    StringBuilder sb = new StringBuilder();
                for (int i = 0; i < array.length; i++) {
        //参数值为空，则不参与签名 这个方法trim()是去空格
        if ((String.valueOf(properties.get(array[i]))).trim().length() > 0) {
            sb.append(array[i]).append(":").append(String.valueOf(properties.get(array[i])).trim());
        }
        if (i != array.length - 1) {
            sb.append(",");
        }
    }
    String cypherSql = String.format("create (n:`%s`{%s}) return n", labelName, sb);
                session.query(cypherSql, new HashMap<>());
                session.clear();*/

    /**
     * 新增实例节点
     *
     * @param node
     * @return
     */
    public void createNodeByWord(NodeSingle node) {
        //处理属性
        Map<String, Object> properties = node.getAttrs();
        properties.put("node_id", "'" + node.getNodeId() + "'");
        //System.out.println("s:" + "'" + node.getNodeId() + "'");
        properties.put("name", node.getName());
        Set<String> keySet = properties.keySet();
        //Map转String
        //1、获取map的key的set集合 转换成String数组
        //2、循环String数组 拼接字符串 每个key value 一组间用 顿号隔开
        String[] array = keySet.toArray(new String[keySet.size()]);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < array.length; i++) {
            //参数值为空，则不参与签名 这个方法trim()是去空格
            if ((String.valueOf(properties.get(array[i]))).trim().length() > 0) {
                sb.append("`").append(array[i]).append("`").append(":").append("'").append(String.valueOf(properties.get(array[i])).trim()).append("'").append(",");
            }
/*            if (i == array.length - 1) {
                break;
                //sb.append(",");
            }*/
        }
        //处理节点的属性，删除连续重复的符号
        StringBuilder answer = new StringBuilder();
        int N = sb.length();
        int i = 0;
        while (i < N) {
            char c = sb.charAt(i);
            answer.append(c);
            while (i < N && sb.charAt(i) == c)
                ++i;
        }
        String newProperties = answer.toString();
        String substring = newProperties.substring(0, newProperties.length() - 1);

        String cypherSql = String.format("create (n:`%s`{%s}) return n", node.getLabelName(), substring);
        session.query(cypherSql, new HashMap<>());
        session.clear();
    }


    /**
     * 新增故障预案
     * @param plan
     */
    public void addFailurePlan(WarningEventFailurePlan plan) {
        //实体 标签名字
        String number = plan.getNumber();
        String s = number.substring(0, 2);
        StringBuffer buffer = new StringBuffer();
        String labelName = buffer.append(s).append("预案").toString();
        //处理属性
        Map<String, Object> properties = new HashMap<>();

        //类别
        String name = plan.getName();
        if (name.contains("母线")) {
            properties.put("类别","母线");
        } else if (name.contains("全站")) {
            properties.put("类别","全站");
        }else{
            properties.put("类别","线路");
        }

        //级别
        properties.put("级别",s);

        properties.put("事故预案名称",plan.getName());
        properties.put("编号",plan.getNumber());
        properties.put("负责单位",plan.getPlace());
        properties.put("创建日期",plan.getCreateDate());
        properties.put("编制人",plan.getProducer());
        properties.put("审核人",plan.getAuditor());
        properties.put("概述",plan.getSummary());
        properties.put("事前运行方式",plan.getBeforeWay());
        properties.put("故障设置",plan.getFaultSetting());
        properties.put("事后运行方式",plan.getAfterWay());
        properties.put("事后风险分析",plan.getAfterRisk());
        properties.put("主要控制目标/南网总调",plan.getTotalNote());
        properties.put("主要控制目标/广东中调",plan.getMiddleNote());
        properties.put("主要控制目标/茂名调控",plan.getRegulation());
        properties.put("事故处理过程及要点",plan.getProcess());
        properties.put("事故信息上报/上报单位",plan.getReportedPlace());
        properties.put("事故信息上报/上报对象",plan.getReportedObject());
        properties.put("事故信息上报/上报内容",plan.getReportedContent());
        properties.put("事故信息发布/发布单位",plan.getPublishPlace());
        properties.put("事故信息发布/发布对象",plan.getPublishObject());
        properties.put("事故信息发布/发布内容",plan.getPublishContent());
        properties.put("事故影响评估",plan.getAssess());
        properties.put("备注",plan.getRemarks());

        //预案的图谱id
        properties.put("node_id", "'" + "2" + "'");
        //System.out.println("s:" + "'" + node.getNodeId() + "'");
        properties.put("name", plan.getName());
        Set<String> keySet = properties.keySet();
        //Map转String
        //1、获取map的key的set集合 转换成String数组
        //2、循环String数组 拼接字符串 每个key value 一组间用 顿号隔开
        String[] array = keySet.toArray(new String[keySet.size()]);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < array.length; i++) {
            //参数值为空，则不参与签名 这个方法trim()是去空格
            if ((String.valueOf(properties.get(array[i]))).trim().length() > 0) {
                sb.append(array[i]).append(":").append(String.valueOf(properties.get(array[i])).trim());
            }
            if (i != array.length - 1) {
                sb.append(",");
            }
        }
        String cypherSql = String.format("create (n:`%s`{%s}) return n", labelName, sb);
        session.query(cypherSql, new HashMap<>());
        session.clear();
    }

    /**
     * 查询所有故障预案
     *
     * @param node_id
     * @return
     */
    public List<NodeSingle> findAllPlan(Long node_id) {
        List<NodeSingle> arrayList = new ArrayList<>();
        String cypherSql = String.format("match (n) where n.node_id = '1' return n", node_id);
        Result query = session.query(cypherSql, new HashMap<>());
        Iterable<Map<String, Object>> maps = query.queryResults();
        for (Map<String, Object> map : maps) {
            NodeSingle node = new NodeSingle();
            NodeModel queryNode = (NodeModel) map.get("n");
            //节点id
            node.setId(queryNode.getId());
            node.setName(queryNode.getLabels().toString());
            //节点属性
            List<Property<String, Object>> propertyList = queryNode.getPropertyList();
            Map<String, Object> proMap = new HashMap<>();
            for (Property<String, Object> property : propertyList) {
                if (proMap.containsKey(property.getKey())) {
                    throw new RuntimeException("数据重复");
                }
                proMap.put(property.getKey(), property.getValue());
                node.setAttrs(proMap);
            }
            arrayList.add(node);
        }
        session.clear();
        return arrayList;
    }
}